<template>
    <el-card style="margin-top:10px">
        <el-form label-width="100px" :model="spuInfo" :rules="spuRules" ref="spuFormRef">
            <el-form-item label="SPU名称" prop="spuName">
                <el-input placeholder="SPU名称" v-model="spuInfo.spuName"></el-input>
            </el-form-item>
            <el-form-item label="品牌" prop="tmId">
                <el-select placeholder="请选择品牌" v-model="spuInfo.tmId">
                    <el-option v-for="tm in trademarkList" :key="tm.id" :label="tm.tmName" :value="tm.id"></el-option>
                </el-select>
            </el-form-item>
            <el-form-item label="SPU描述" prop="description">
                <el-input type="textarea" :rows="3" v-model="spuInfo.description"></el-input>
            </el-form-item>
            <el-form-item label="SPU图片" prop="spuImageList">
                <el-upload v-model:file-list="spuInfo.spuImageList as any" :action="`${BASE_URL}/admin/product/fileUpload`"
                    list-type="picture-card" :on-preview="handlePictureCardPreview" :on-remove="handleRemove"
                    :on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload">
                    <el-icon>
                        <Plus />
                    </el-icon>
                </el-upload>

                <el-dialog v-model="dialogVisible">
                    <img w-full :src="dialogImageUrl" alt="Preview Image" />
                </el-dialog>
            </el-form-item>
            <el-form-item label="销售属性" prop="spuSaleAttrList">
                <el-select :placeholder="`还剩下${filterbaseSaleAttrList.length}个未选择`" v-model="spuInfo.spuSaleAttr">
                    <el-option v-for="attr in  filterbaseSaleAttrList" :key="attr.id" :value="`${attr.id}:${attr.name}`"
                        :label="attr.name"></el-option>
                </el-select>
                <el-button type="primary" :disabled="!spuInfo.spuSaleAttr" :icon="Plus" style="margin-left:10px"
                    @click="toAddBaseSaleAttr">添加销售属性</el-button>
            </el-form-item>
            <el-form-item>
                <el-table border :data="spuInfo.spuSaleAttrList">
                    <el-table-column label="序号" width="80px" type="index" align="center"></el-table-column>
                    <el-table-column label="属性名" prop="saleAttrName"></el-table-column>
                    <el-table-column label="属性值名称列表">
                        <template v-slot="{ row }">
                            <el-tag v-for="(tag, index) in row.spuSaleAttrValueList" :key="tag" class="mx-1" closable
                                :disable-transitions="false" @close="handleClose(row, index)" style="margin-right:5px">
                                {{ tag.saleAttrValueName }}
                            </el-tag>
                            <el-input v-if="row.inputVisible" ref="InputRef" v-model="inputValue" class="ml-1 w-20"
                                size="small" @keyup.enter="handleInputConfirm(row)" @blur="handleInputConfirm(row)" />
                            <el-button v-else class="button-new-tag ml-1" size="small" @click="showInput(row)">
                                + New Tag
                            </el-button>
                        </template>
                    </el-table-column>
                    <el-table-column label="操作">
                        <template v-slot="{ row, $index }">
                            <el-popconfirm confirm-button-text="Yes" cancel-button-text="No" title="真的要删除此属性吗?"
                                @confirm="deleteAttrConfirm($index)">
                                <template #reference>
                                    <div style="display: inline-block; margin-left: 10px">
                                        <el-tooltip class="box-item" effect="dark" content="删除属性" placement="top">
                                            <el-button type="danger" size="small" :icon="Delete"></el-button>
                                        </el-tooltip>
                                    </div>
                                </template>
                            </el-popconfirm>
                        </template>
                    </el-table-column>
                </el-table>
            </el-form-item>
            <el-form-item>
                <el-button type="primary" @click="submitSpuForm(spuFormRef)">保存</el-button>
                <el-button @click="emits('changStatus', ShowStatus.SPU_LIST)">取消</el-button>
            </el-form-item>
        </el-form>
    </el-card>
</template>
  
<script lang="ts">

export default {
    name: 'SpuForm'
}
</script>

<script setup lang="ts">
import { ElMessage, type FormInstance, type FormRules, type UploadProps, type UploadUserFile, ElInput, } from 'element-plus'
import { Plus, Delete, InfoFilled } from '@element-plus/icons-vue'
import { onMounted, ref, reactive, computed } from 'vue'
import { reqGetTredemarkListData, reqGetBaseSaleAttrList, reqSaveSpuInfo, reqGetSpuImageListData, reqGetSpuSaleAttrListData, reqUpdateSpuInfo } from '@/api/product/spu'
import { nextTick } from 'vue'
import { ShowStatus } from './types'
import { useCategoryListStore } from '@/stores/categoryList'
import type { SpuImageListModel, SpuInfoModel, BaseSaleAttrModel, SpuSaleAttrModel, SpuImageModel, BaseSaleAttrListModel } from '@/api/product/model/spuModel'
import type { TrademarkListModel } from '@/api/product/model/trademarkModel'
//图片上传地址
const BASE_URL = import.meta.env.VITE_API_URL;
const dialogImageUrl = ref('')
const dialogVisible = ref(false)
const fileList = ref<UploadUserFile[]>([])

//tag标签
const inputValue = ref('') //输入框内容
const dynamicTags = ref(['Tag 1', 'Tag 2', 'Tag 3']) //tag标签内容
const inputVisible = ref(false) //控制tag输入框是否显示
const InputRef = ref<InstanceType<typeof ElInput>>() //input元素


//品牌数据
const trademarkList = ref<TrademarkListModel>([])
//属性数据
const baseSaleAttrList = ref<BaseSaleAttrListModel>([])

//组件切换的自定义事件
const emits = defineEmits(['changStatus'])

//引入store
const categoryStore = useCategoryListStore()

//接受父组件传递的信息
const props = defineProps<{
    currentSpuInfo: SpuInfoModel; // 传入的时候， 也要添加类型约束
}>()


const spuInfo = reactive<SpuInfoModel>(props.currentSpuInfo)

// 添加校验规则
const spuRules = reactive<FormRules>({
    spuName: [
        { required: true, message: '请输入SPU名称', trigger: 'blur' },
        { min: 1, max: 10, message: 'SPU名称在1-10个字符之间', trigger: 'blur' }
    ],
    tmId: [{ required: true, message: '请选择SPU品牌', trigger: 'change' }],
    description: [{ required: true, message: '请输入SPU描述', trigger: 'blur' }],
    spuImageList: [{ required: true, message: '请选择一张图片', type: 'array', trigger: 'change' }],
    spuSaleAttrList: [{ required: true, message: '请至少添加一个属性', type: 'array', trigger: 'click' }]
})

//绑定form表单元素
const spuFormRef = ref<FormInstance>()
// console.log(spuFormRef)


onMounted(async () => {
    // Promise.all() 可以一次性发送多个请求 只要有一个失败 则结果为失败 反之成功
    // Promise.race() 赛跑机制  也可以一次性发送多个请求 哪个快就用哪个
    // Promise.allSettled() 语法同all 不一样的是，允许有失败的请求 不影响成功的请求
    // allSettled 返回值是一个对象 {status:'fullfiled',value:[]} {status:'rejected',}
    try {
        let promise1 = reqGetTredemarkListData()
        let promise2 = reqGetBaseSaleAttrList()
        let promise3;
        let promise4;

        const { id } = spuInfo
        if (id) {
            promise3 = reqGetSpuImageListData(id)
            promise4 = reqGetSpuSaleAttrListData(id)
        }
        const [resTredemarkList, resbaseSaleAttrList, resSpuImageList, resSpuSaleAttrList] = await Promise.all([promise1, promise2, promise3, promise4])
        console.log(resTredemarkList, resbaseSaleAttrList)
        trademarkList.value = resTredemarkList
        baseSaleAttrList.value = resbaseSaleAttrList
        if (resSpuImageList && resSpuSaleAttrList) {
            spuInfo.spuImageList = resSpuImageList.map(item => {
                return {
                    ...item,
                    name: item.imgName,
                    url: item.imgUrl,
                }
            })
            spuInfo.spuSaleAttrList = resSpuSaleAttrList
        }
        // console.log(trademarkList.value)
        // console.log(baseSaleAttrList.value)
    } catch (error) {
        ElMessage.error('获取属性失败')
    }

})



//添加销售属性
const toAddBaseSaleAttr = () => {
    //如果有添加属性，并且属性值为空，要先添加属性值
    if (spuInfo.spuSaleAttrList.length && spuInfo.spuSaleAttrList.some(item => item.spuSaleAttrValueList.length === 0)) {
        ElMessage.error('有属性值为空，请添加...')
        return
    }
    const [baseSaleAttrId, saleAttrName] = spuInfo.spuSaleAttr!.split(':')
    // console.log(spuInfo)
    spuInfo.spuSaleAttrList.push({
        inputVisible: false,
        baseSaleAttrId, //属性id
        saleAttrName, // 属性名,
        spuSaleAttrValueList: [] // 用来存储属性值
    })
    spuInfo.spuSaleAttr = ''
}

//图片上传成功之前的校验
const beforeAvatarUpload: UploadProps["beforeUpload"] = (rawFile) => {
    const imgArr = ["image/jpeg", "image/png"];
    if (!imgArr.includes(rawFile.type)) {
        ElMessage.error('图片格式必须是"image/jpeg或image/png"!');
        return false;
    } else if (rawFile.size / 1024 / 1024 > 2) {
        console.log(rawFile.size / 1024 / 1024);
        ElMessage.error("图片大小不能超过2M!");
        return false;
    }
    return true;
};

//图片上传成功之后保存地址
const handleAvatarSuccess: UploadProps["onSuccess"] = (
    response,
    uploadFile, uploadFiles
) => {
    spuInfo.spuImageList = uploadFiles as SpuImageListModel
    console.log(spuInfo.spuImageList)

    //清空校验规则
    spuFormRef.value!.clearValidate(['spuImageList'])
}

// 删除图片
const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {
    //
    spuInfo.spuImageList = uploadFiles as SpuImageListModel
}
//图片预览
const handlePictureCardPreview: UploadProps['onPreview'] = uploadFile => {
    dialogImageUrl.value = uploadFile.url!
    dialogVisible.value = true
}

//获取剩余基础销售属性
const filterbaseSaleAttrList = computed(() => {
    return baseSaleAttrList.value.filter((baseSaleAttr) => {
        return !spuInfo.spuSaleAttrList.find(item => baseSaleAttr.name === item.saleAttrName)
    })
})

//删除销售属性项
const deleteAttrConfirm = (index: number) => {
    spuInfo.spuSaleAttrList.splice(index, 1)
}

//删除销售属性值
const handleClose = (row: SpuSaleAttrModel, index: number) => {
    //删除一个tag标签
    row.spuSaleAttrValueList.splice(index, 1)
}

//添加tag标签时触发
const showInput = (row: SpuSaleAttrModel) => {
    row.inputVisible = true
    nextTick(() => {
        InputRef.value!.input!.focus()
    })
}

//tag标签输入框失去焦点时添加tagetSpuInfo
const handleInputConfirm = (row: SpuSaleAttrModel) => {
    if (inputValue.value) {
        //查找正在添加的属性值是否重复了
        if (row.spuSaleAttrValueList.find(item => item.saleAttrValueName === inputValue.value)) {
            ElMessage.error('添加的属性值不能重复,请更换一个')
            row.inputVisible = false
            inputValue.value = ''
            return
        }
        // dynamicTags.value.push(inputValue.value)
        const { baseSaleAttrId, saleAttrName } = row
        row.spuSaleAttrValueList.push({
            baseSaleAttrId,
            isChecked: "0",
            saleAttrName,
            saleAttrValueName: inputValue.value
        })
    }
    row.inputVisible = false
    inputValue.value = ''
}

//spuform表单保存时校验数据
const submitSpuForm = async (formEl: FormInstance | undefined) => {
    if (!formEl) return
    await formEl.validate(async (valid, fields) => {
        if (valid) {
            // 1. 在最后单击`保存`按钮之前，如果添加了某个属性，但是属性值有空项，也是不能提交的。
            // 2. 再一个，spuImageList中的数据也不符合服务器端的要求，，做进一步的处理，以满足服务器端的参数格式要求，服务器商标要求上传的图片有两个属性，imgUrl, imgName
            const spuSaleAttrList = spuInfo.spuSaleAttrList
            if (spuSaleAttrList.length && spuSaleAttrList.every(item => item.spuSaleAttrValueList.length === 0)) {
                ElMessage.error('有属性值为空，请添加...')
                return
            }
            //设置提交图片的格式
            spuInfo.spuImageList = spuInfo.spuImageList.map((item): SpuImageModel => {
                return {
                    imgName: item.name as string,
                    imgUrl: item.response?.data || item.url as string
                }
            })
            //设置三级导航id值
            spuInfo.category3Id = categoryStore.category3Id as number
            if (spuInfo.id) {
                //此时是更新
                await reqUpdateSpuInfo(spuInfo)
            } else {
                //此时是添加spuInfo
                await reqSaveSpuInfo(spuInfo)
            }
            ElMessage.success('提交spu数据成功')
            //添加成功时，要跳转到spuList页面
            emits('changStatus', ShowStatus.SPU_LIST)
        } else {
            console.log('error submit!')
            return false
        }
    })
}


</script>
  
<style></style>